/**
* @file arm_2d_scene_mainmenu.c
* @brief scene mainmenu
* @details 
* @author huangbin
* @version V1.0.0
* @date 2025-06-14
* @copyright All documents are copyrighted by Shenzhen Xinlongwei Technology Co., LTD.
*            They may not be used for commercial purposes without permission
*/

/*============================ INCLUDES ======================================*/

#define __USER_SCENE_MAINMENU_IMPLEMENT__
#include "inc.h"
#include "arm_2d_scene_mainmenu.h"


#if defined(RTE_Acceleration_Arm_2D_Helper_PFB)

#include <stdlib.h>
#include <string.h>

#if defined(__clang__)
#   pragma clang diagnostic push
#   pragma clang diagnostic ignored "-Wunknown-warning-option"
#   pragma clang diagnostic ignored "-Wreserved-identifier"
#   pragma clang diagnostic ignored "-Wsign-conversion"
#   pragma clang diagnostic ignored "-Wpadded"
#   pragma clang diagnostic ignored "-Wcast-qual"
#   pragma clang diagnostic ignored "-Wcast-align"
#   pragma clang diagnostic ignored "-Wmissing-field-initializers"
#   pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#   pragma clang diagnostic ignored "-Wmissing-prototypes"
#   pragma clang diagnostic ignored "-Wunused-variable"
#   pragma clang diagnostic ignored "-Wgnu-statement-expression"
#   pragma clang diagnostic ignored "-Wdeclaration-after-statement"
#   pragma clang diagnostic ignored "-Wunused-function"
#   pragma clang diagnostic ignored "-Wmissing-declarations"
#   pragma clang diagnostic ignored "-Wimplicit-int-conversion" 
#elif __IS_COMPILER_ARM_COMPILER_5__
#   pragma diag_suppress 64,177
#elif __IS_COMPILER_IAR__
#   pragma diag_suppress=Pa089,Pe188,Pe177,Pe174
#elif __IS_COMPILER_GCC__
#   pragma GCC diagnostic push
#   pragma GCC diagnostic ignored "-Wformat="
#   pragma GCC diagnostic ignored "-Wpedantic"
#   pragma GCC diagnostic ignored "-Wunused-function"
#   pragma GCC diagnostic ignored "-Wunused-variable"
#   pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
#endif

/*============================ MACROS ========================================*/

/*============================ MACROFIED FUNCTIONS ===========================*/
#undef this
#define this (*ptThis)

/*============================ TYPES =========================================*/
/*============================ GLOBAL VARIABLES ==============================*/

/*============================ PROTOTYPES ====================================*/
/*============================ LOCAL VARIABLES ===============================*/

/*! define dirty regions */
IMPL_ARM_2D_REGION_LIST(s_tDirtyRegions, static)

    /* a dirty region to be specified at runtime*/
    ADD_REGION_TO_LIST(s_tDirtyRegions,
        0  /* initialize at runtime later */
    ),
    
    /* add the last region:
        * it is the top left corner for text display 
        */
    ADD_LAST_REGION_TO_LIST(s_tDirtyRegions,
        .tLocation = {
            .iX = 0,
            .iY = 0,
        },
        .tSize = {
            .iWidth = 0,
            .iHeight = 8,
        },
    ),

END_IMPL_ARM_2D_REGION_LIST(s_tDirtyRegions)

/*============================ IMPLEMENTATION ================================*/

static void __on_scene_mainmenu_load(arm_2d_scene_t *ptScene)
{
    user_scene_mainmenu_t *ptThis = (user_scene_mainmenu_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}

static void __after_scene_mainmenu_switching(arm_2d_scene_t *ptScene)
{
    user_scene_mainmenu_t *ptThis = (user_scene_mainmenu_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}

static void __on_scene_mainmenu_depose(arm_2d_scene_t *ptScene)
{
    user_scene_mainmenu_t *ptThis = (user_scene_mainmenu_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

    /*--------------------- insert your depose code begin --------------------*/
    

    /*---------------------- insert your depose code end  --------------------*/

    arm_foreach(int64_t,this.lTimestamp, ptItem) {
        *ptItem = 0;
    }
    gui_unregister_msg_handler(guiGetInstance(),&this.msg_event);
    ptScene->ptPlayer = NULL;
    if (!this.bUserAllocated) {
        __arm_2d_free_scratch_memory(ARM_2D_MEM_TYPE_UNSPECIFIED, ptScene);
    }
}

/*----------------------------------------------------------------------------*
 * Scene mainmenu                                                                    *
 *----------------------------------------------------------------------------*/
#if 0  /* deprecated */
static void __on_scene_mainmenu_background_start(arm_2d_scene_t *ptScene)
{
    user_scene_mainmenu_t *ptThis = (user_scene_mainmenu_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}

static void __on_scene_mainmenu_background_complete(arm_2d_scene_t *ptScene)
{
    user_scene_mainmenu_t *ptThis = (user_scene_mainmenu_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}
#endif


static void __on_scene_mainmenu_frame_start(arm_2d_scene_t *ptScene)
{
    user_scene_mainmenu_t *ptThis = (user_scene_mainmenu_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}

static void __on_scene_mainmenu_frame_complete(arm_2d_scene_t *ptScene)
{
    user_scene_mainmenu_t *ptThis = (user_scene_mainmenu_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

#if 0
    /* switch to next scene after 3s */
    if (arm_2d_helper_is_time_out(3000, &this.lTimestamp[0])) {
        arm_2d_scene_player_switch_to_next_scene(ptScene->ptPlayer);
    }
#endif
}

static void __before_scene_mainmenu_switching_out(arm_2d_scene_t *ptScene)
{
    user_scene_mainmenu_t *ptThis = (user_scene_mainmenu_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}
extern const arm_2d_tile_t c_tileicon_clockRGB565;
extern const arm_2d_tile_t c_tileicon_clockMask;
extern const arm_2d_tile_t c_tileicon_meterRGB565;
extern const arm_2d_tile_t c_tileicon_meterMask;
extern const arm_2d_tile_t c_tileicon_musicRGB565;
extern const arm_2d_tile_t c_tileicon_musicMask;
const arm_2d_region_t icon_coordinate[] = {
    {20,20,80,80},
    {120,20,80,80},
    {220,20,80,80},
};
static
IMPL_PFB_ON_DRAW(__pfb_draw_scene_mainmenu_handler)
{
    ARM_2D_PARAM(pTarget);
    ARM_2D_PARAM(ptTile);
    ARM_2D_PARAM(bIsNewFrame);

    user_scene_mainmenu_t *ptThis = (user_scene_mainmenu_t *)pTarget;

    arm_2d_canvas(ptTile, __top_canvas) {
    /*-----------------------draw the scene begin-----------------------*/
        /* following code is just a demo, you can remove them */
        arm_2d_dock_top(__top_canvas,120){
//        arm_2d_region_t tRegion = __top_region;
//        tRegion.tLocation.iX = 20;//(320-240)/4;
//        tRegion.tLocation.iY = 20;
         arm_2d_region_t tRegion;
         tRegion = icon_coordinate[0];
        arm_2d_tile_copy_with_src_mask(&c_tileicon_clockRGB565,
                                    &c_tileicon_clockMask,
                                    ptTile,
                                    &tRegion,
                                    ARM_2D_CP_MODE_COPY);
         tRegion = icon_coordinate[1];
        arm_2d_tile_copy_with_src_mask(&c_tileicon_meterRGB565,
                                    &c_tileicon_meterMask,
                                    ptTile,
                                    &tRegion,
                                    ARM_2D_CP_MODE_COPY);
        tRegion = icon_coordinate[2];
        arm_2d_tile_copy_with_src_mask(&c_tileicon_musicRGB565,
                                    &c_tileicon_musicMask,
                                    ptTile,
                                    &tRegion,
                                    ARM_2D_CP_MODE_COPY);    
        tRegion.tLocation.iX = ptThis->chSelectItem * 100 + 20 -4;
        tRegion.tLocation.iY -= 4;
        tRegion.tSize.iWidth = 88;
        tRegion.tSize.iHeight = 88;
         draw_round_corner_border(   ptTile,&tRegion,GLCD_COLOR_RED, 
                                        (arm_2d_border_opacity_t){255,255,255,255},
                                        (arm_2d_corner_opacity_t){255,255,255,255});                                    
        }

//        /* draw text at the top-left corner */

//        arm_lcd_text_set_target_framebuffer((arm_2d_tile_t *)ptTile);
//        arm_lcd_text_set_font(&ARM_2D_FONT_6x8.use_as__arm_2d_font_t);
//        arm_lcd_text_set_draw_region(NULL);
//        arm_lcd_text_set_colour(GLCD_COLOR_RED, GLCD_COLOR_WHITE);
//        arm_lcd_text_location(0,0);
//        arm_lcd_puts("Scene mainmenu");

    /*-----------------------draw the scene end  -----------------------*/
    }
    ARM_2D_OP_WAIT_ASYNC();

    return arm_fsm_rt_cpl;
}
static bool arm_2d_scene_event_handle(xm_gui_t *ptGUI, void  *pTarget,gui_msg_core_t *ptMSG);
ARM_NONNULL(1)
user_scene_mainmenu_t *__arm_2d_scene_mainmenu_init(   arm_2d_scene_player_t *ptDispAdapter, 
                                        user_scene_mainmenu_t *ptThis)
{
    bool bUserAllocated = false;
    assert(NULL != ptDispAdapter);

    s_tDirtyRegions[dimof(s_tDirtyRegions)-1].ptNext = NULL;

    /* get the screen region */
    arm_2d_region_t __top_canvas
        = arm_2d_helper_pfb_get_display_area(
            &ptDispAdapter->use_as__arm_2d_helper_pfb_t);
    
    /* initialise dirty region 0 at runtime
     * this demo shows that we create a region in the centre of a screen(320*240)
     * for a image stored in the tile c_tileCMSISLogoMask
     */
//    arm_2d_align_centre(__top_canvas, c_tileCMSISLogoMask.tRegion.tSize) {
//        s_tDirtyRegions[0].tRegion = __centre_region;
//    }

    s_tDirtyRegions[dimof(s_tDirtyRegions)-1].tRegion.tSize.iWidth 
                                                        = __top_canvas.tSize.iWidth;

    if (NULL == ptThis) {
        ptThis = (user_scene_mainmenu_t *)
                    __arm_2d_allocate_scratch_memory(   sizeof(user_scene_mainmenu_t),
                                                        __alignof__(user_scene_mainmenu_t),
                                                        ARM_2D_MEM_TYPE_UNSPECIFIED);
        assert(NULL != ptThis);
        if (NULL == ptThis) {
            return NULL;
        }
    } else {
        bUserAllocated = true;
    }

    memset(ptThis, 0, sizeof(user_scene_mainmenu_t));

    *ptThis = (user_scene_mainmenu_t){
        .use_as__arm_2d_scene_t = {

            /* the canvas colour */
            .tCanvas = {GLCD_COLOR_BLACK}, 

            /* Please uncommon the callbacks if you need them
             */
            .fnOnLoad       = &__on_scene_mainmenu_load,
            .fnScene        = &__pfb_draw_scene_mainmenu_handler,
            .fnAfterSwitch  = &__after_scene_mainmenu_switching,

            /* if you want to use predefined dirty region list, please uncomment the following code */
            //.ptDirtyRegion  = (arm_2d_region_list_item_t *)s_tDirtyRegions,
            
            //.fnOnBGStart    = &__on_scene_mainmenu_background_start,        /* deprecated */
            //.fnOnBGComplete = &__on_scene_mainmenu_background_complete,     /* deprecated */
            .fnOnFrameStart = &__on_scene_mainmenu_frame_start,
            .fnBeforeSwitchOut = &__before_scene_mainmenu_switching_out,
            .fnOnFrameCPL   = &__on_scene_mainmenu_frame_complete,
            .fnDepose       = &__on_scene_mainmenu_depose,

            .bUseDirtyRegionHelper = false,
        },
        .bUserAllocated = bUserAllocated,
    };

    /* ------------   initialize members of user_scene_mainmenu_t begin ---------------*/


    /* ------------   initialize members of user_scene_mainmenu_t end   ---------------*/

    arm_2d_scene_player_append_scenes(  ptDispAdapter, 
                                        &this.use_as__arm_2d_scene_t, 
                                        1);
	{

		this.msg_event.fnHandler = arm_2d_scene_event_handle;
		this.msg_event.pTarget = ptThis;
		this.msg_event.ptNext = NULL;
		gui_register_msg_handler(guiGetInstance(),&this.msg_event);
	}
    return ptThis;
}
#include "arm_2d_scene_watch.h"
#include "arm_2d_scene_music_player.h"
#include "arm_2d_scene_meter.h"
#include "arm_2d_scene_fitness.h"

static bool arm_2d_scene_event_handle(xm_gui_t *ptGUI, void  *pTarget,gui_msg_core_t *ptMSG)
{
	user_scene_mainmenu_t *ptThis = (user_scene_mainmenu_t *)pTarget;
	uint8_t chMsgId = gui_helper_msg_item_get_id(ptMSG);
	switch(chMsgId)
	{
		break;
		case GUI_MSG_KEY_EVT_DOWN:
		case GUI_MSG_KEY_EVT_REPEAT:
		{
			
			gui_msg_key_evt_t *ptKeyMSG = (gui_msg_key_evt_t *)ptMSG;
			DebugPrintf("Key Message = %s,key value = %d,,pTarget=%d\r\n",gui_helper_msg_get_name(ptMSG),ptKeyMSG->hwKeyValue,pTarget);
			if(ptKeyMSG->hwKeyValue == VK_DOWN)
			{
                ptThis->chSelectItem ++;
               ptThis->chSelectItem = ptThis->chSelectItem % 3;
			}
            else if(ptKeyMSG->hwKeyValue == VK_UP)
            {
                if( ptThis->chSelectItem)
                     ptThis->chSelectItem--;
                else
                     ptThis->chSelectItem = 2;
            }
		}
		break;
		case GUI_MSG_POINTER_EVT_UP:
		case GUI_MSG_POINTER_EVT_HOLD:
		case GUI_MSG_POINTER_EVT_DOWN:
        {
            gui_msg_pointer_evt_t *ptPointerMSG = (gui_msg_pointer_evt_t *)ptMSG;
            int16_t x = ptPointerMSG->use_as__arm_2d_location_t.iX;
            int16_t y = ptPointerMSG->use_as__arm_2d_location_t.iY;
			DebugPrintf("pointer Message = %s,x = %d,y = %d\r\n",gui_helper_msg_get_name(ptMSG),x,y);
#if USE_MENU_DEMO == 1		
            if(chMsgId == GUI_MSG_POINTER_EVT_UP)
            {
                if(ptInRect(x,y,(arm_2d_region_t*)&icon_coordinate[0]))
                {
                    ptThis->chSelectItem = 0;
                    arm_2d_scene_watch_init(ptThis->use_as__arm_2d_scene_t.ptPlayer);
                    arm_2d_scene_player_switch_to_next_scene(ptThis->use_as__arm_2d_scene_t.ptPlayer);
                }
                else if(ptInRect(x,y,(arm_2d_region_t*)&icon_coordinate[1]))
                {
                    ptThis->chSelectItem = 1;
//                    arm_2d_scene_meter_init(ptThis->use_as__arm_2d_scene_t.ptPlayer);
                    arm_2d_scene_fitness_init(ptThis->use_as__arm_2d_scene_t.ptPlayer);
                    arm_2d_scene_player_switch_to_next_scene(ptThis->use_as__arm_2d_scene_t.ptPlayer);
                }
                else if(ptInRect(x,y,(arm_2d_region_t*)&icon_coordinate[2]))
                {
                    ptThis->chSelectItem = 2;
                    arm_2d_scene_music_player_init(ptThis->use_as__arm_2d_scene_t.ptPlayer);
                    arm_2d_scene_player_switch_to_next_scene(ptThis->use_as__arm_2d_scene_t.ptPlayer);
                }
            }
#endif			
        }
        break;
		case GUI_MSG_KEY_EVT_UP:
        {
        }
		break;
		case GUI_MSG_WIDGETS_EVT_TIMER:
		break;
		case GUI_MSG_WIDGETS_EVT_COMM:
		default:
		return false;
	}
	return true;
}

#if defined(__clang__)
#   pragma clang diagnostic pop
#endif

#endif


